//////////////////////////////////////////////////////////////////////////
//  drm_brew.c
//////////////////////////////////////////////////////////////////////////

#include "brew_incs.h"
#include "nf3_incs.h"


#include "kal_release.h"        /* Basic data type */
//#include "App_buff_alloc.h"
//#include "stack_common.h"
//#include "stack_msgs.h"

#include "fs_type.h"
#include "fat_fs.h"
#include "wbrs_utils.h"

#include "drm_brew_dep.h"

#include "drm_def.h"
#include "drm_util.h"
#include "drm_main.h"
#include "drm_gprot.h"


const short nf_str_line[2] = {0x002F, 0x0000};  // '/'
const short nf_str_Noname[7] = {0x004E, 0x006F, 0x006E, 0x0061, 0x006D, 0x0065, 0x0000};


//
//---------------------------------------------------------------------------------
extern 	IFileMgr *NF3_GetFileMgr( void );



//
//---------------------------------------------------------------------------------
int FS_ParseFH(FS_HANDLE FileHandle)
{

	return FileHandle;
}


//
//---------------------------------------------------------------------------------
#if 0
void kal_prompt_trace(int mod_id, const char *fmt, ...)
{
   	va_list argList;
   	if ((mod_id == MOD_MMI) || (mod_id == MOD_K7WAP) || 
   			(mod_id == MOD_WAP) || (mod_id == MOD_K7PUSH))
 	va_start(argList, fmt); 
 	va_end(argList);	
}
#endif


//
//---------------------------------------------------------------------------------
void applib_dt_get_secure_time(applib_time_struct *t)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    /* for customer to provide specific secure clock mechanism */
//    applib_dt_get_rtc_time(t);
}

//
//---------------------------------------------------------------------------------
kal_uint32 applib_dt_mytime_2_utc_sec(applib_time_struct *currTime, kal_bool daylightSaving)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_uint16 i;
    kal_uint32 no_of_days = 0;
    kal_int32 utc_time = 0;
    kal_int32 is_leap;
    kal_uint8 dst;

#if 0
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (currTime->nYear < DT_UTC_BASE_YEAR)
    {
        return 0;
    }

    /* year */
    for (i = DT_UTC_BASE_YEAR; i < currTime->nYear; i++)
    {
        no_of_days += (365 + applib_dt_is_leap_year(i));
    }

    /* month */
    is_leap = applib_dt_is_leap_year(currTime->nYear);
    for (i = 1; i < currTime->nMonth; i++)
    {
        no_of_days += applib_dt_last_day_of_mon((kal_uint8) i, currTime->nYear);
    }

    /* day */
    no_of_days += (currTime->nDay - 1);

    /* sec */
    utc_time =
        (kal_uint32) no_of_days *DT_SEC_PER_DAY + (kal_uint32) (currTime->nHour * DT_SEC_PER_HOUR +
                                                                currTime->nMin * DT_SEC_PER_MIN + currTime->nSec);

    dst = applib_dt_is_dst_enabled();

    if (dst && daylightSaving)
    {
        utc_time -= DT_SEC_PER_HOUR;
    }

#endif    
    return utc_time;
}


//
//---------------------------------------------------------------------------------
int 	FS_Open( const WCHAR *FileName, UINT Flag )
{
	OpenFileMode 	mode;
	char 			fname[256] = { 0 };
	IFile	 		*pIFile = NULL;


	if( !FileName )
		return FS_INVALID_FILENAME;
	
	_UnicodeStr2Ascii( (_LPWORD)FileName, (_LPBYTE)fname );
//	STRCPY( (char*)fname, (const char*)"fs:/shared/ftl/Received/LTtest.drm" );

    if( (Flag & FS_CREATE_ALWAYS) )
    {
		// Judge file exist
		if( SUCCESS == IFILEMGR_Test( NF3_GetFileMgr(), (char*)fname ) )
		{
			IFILEMGR_Remove( NF3_GetFileMgr(), (char*)fname );
		}
	}

	switch( Flag )
	{
	case FS_CREATE:
	case FS_CREATE_ALWAYS:
		mode = _OFM_CREATE;
		break ;

	case FS_READ_WRITE:
		mode = _OFM_READWRITE;
		break ;

	case FS_READ_ONLY:
	default:
		mode = _OFM_READ;
		break ;
	}
	
 	pIFile = (IFile*)wtkOpenFile( (const char*)fname, mode );
	if( pIFile == NULL )
	{
		return FS_INVALID_FILENAME;
	}

	return (int)pIFile;
}


//
//---------------------------------------------------------------------------------
int FS_Write( FS_HANDLE FileHandle, void *DataPtr, UINT Length, UINT *Written )
{
	if( (FileHandle < FS_NO_ERROR) || (NULL == DataPtr) )
	{
		return FS_INVALID_FILENAME;
	}

	*Written = IFILE_Write( (IFile*)FileHandle, DataPtr, Length );

    return FS_NO_ERROR;
}

//
//---------------------------------------------------------------------------------
int FS_Read( FS_HANDLE FileHandle, void *DataPtr, UINT Length, UINT *Read )
{
	if( (FileHandle < FS_NO_ERROR) || (NULL == DataPtr) )
	{
		return FS_INVALID_FILENAME;
	}

	*Read = IFILE_Read( (IFile*)FileHandle, DataPtr, Length );
	
    return FS_NO_ERROR;
}

//
//---------------------------------------------------------------------------------
int FS_Close( FS_HANDLE File )
{
	return IFILE_Release( (IFile*)File );
}


//
//---------------------------------------------------------------------------------
int FS_Seek( FS_HANDLE FileHandle, int Offset, int Whence )
{
	int		seekFlag;

	if( (FileHandle < FS_NO_ERROR) )
	{
		return FS_INVALID_FILENAME;
	}

	switch( Whence )
	{
	case FS_FILE_CURRENT:
		seekFlag = _SEEK_CURRENT;
		break ;

	case FS_FILE_END:
		seekFlag = _SEEK_END;
		break ;

	case FS_FILE_BEGIN:
	default:
		seekFlag = _SEEK_START;
		break ;
	}

	return IFILE_Seek( (IFile*)FileHandle, seekFlag, Offset );
}


//
//---------------------------------------------------------------------------------
int FS_GetFileInfo(FS_HANDLE FileHandle, FS_FileInfo *FileInfo)
{
#if 0
    int map_fh=0;

    ASSERT(FileInfo != NULL);

    /* verify file handle */

    if (FileHandle > FSSIM_MAX_FILE || FileHandle <= 0)

        return FS_INVALID_FILE_HANDLE;

    else if (fssim_file[FileHandle].state != STATE_INUSE)

        return FS_INVALID_FILE_HANDLE;

    else if (fssim_vfgen.link[FileHandle] > 0)

        map_fh = fssim_vfgen.link[FileHandle];

    else if (fssim_file[FileHandle].handle == INVALID_HANDLE_VALUE)
        
        return FS_INVALID_FILE_HANDLE;

    FileInfo->DirEntry = &(fssim_file[FileHandle].DirEntry);

    fssim_update_direntry_datetime(FileHandle, &(fssim_file[FileHandle].DirEntry));

    FileInfo->FullName = (char *)fssim_file[FileHandle].filename;

    if (map_fh > 0) {

        /* virtual file */

        FileInfo->FilePos = fssim_vfgen.pos[FileHandle];
        FileInfo->AllocatedSize = 0;

    } else {

        FileInfo->FilePos = SetFilePointer(fssim_file[FileHandle].handle, 0, NULL, FILE_CURRENT);
        FileInfo->AllocatedSize = GetFileSize(fssim_file[FileHandle].handle, NULL);
    }

    FileInfo->ClusterChains = 0;

    FileInfo->VolumeSerialNumber = 0;
#endif

    return FS_NO_ERROR;
}


//
//---------------------------------------------------------------------------------
int FS_Delete(const WCHAR * FileName)
{ 
	char			fname[256] = { 0 };
	IFile			*pIFile = NULL;


	if( !FileName )
		return FS_INVALID_FILENAME;

	_UnicodeStr2Ascii( (_LPWORD)FileName, (_LPBYTE)fname );

	IFILEMGR_Remove( NF3_GetFileMgr(), (char*)fname );
	
    return FS_NO_ERROR;
}


//
//---------------------------------------------------------------------------------
int FS_Truncate(FS_HANDLE FileHandle)
{
	return FS_NO_ERROR;
}

//
//---------------------------------------------------------------------------------
int FS_Rename(const WCHAR *FileName, const WCHAR *NewName)
{
	return FS_NO_ERROR;
}


//
//---------------------------------------------------------------------------------
int FS_GetDiskInfo(const WCHAR *DriveName, FS_DiskInfo *DiskInfo, int Flags)
{
	return FS_NO_ERROR;
}


//
// Use to replace FS_GetDiskInfo to get free disk space
//---------------------------------------------------------------------------------
kal_uint32 FS_GetFreeSpace( const WCHAR *DriveName, int Flags )
{
	uint32			dwTotal = 0;
	uint32			dwFree = 0;
	kal_uint32		disk_free_size = 0;
	char			diskpath[256] = { 0 };


	if( !DriveName )
		return 0;

	_UnicodeStr2Ascii( (_LPWORD)DriveName, (_LPBYTE)diskpath );

	IFILEMGR_GetFreeSpaceEx( NF3_GetFileMgr(), diskpath, (uint32*)&dwTotal, (uint32*)&dwFree );

	disk_free_size = (kal_uint32)dwFree;

	return disk_free_size;
}


/*************************************************************************/
/*      FS_GetFilePosition                                               */
/* DESCRIPTION                                                           */
/*      This function is used to the current file pointer.               */
/* INPUTS                                                                */
/*      FileHandle   -  file handl of file to get the file pointer       */
/*      Position     -  storage for the current file pointer             */
/* OUTPUTS                                                               */
/*      Error code                                                       */
/*************************************************************************/
int FS_GetFilePosition( FS_HANDLE FileHandle, UINT *Position )
{
	UINT	FilePos = 0;

	if( (FileHandle < FS_NO_ERROR) )
	{
		return FS_INVALID_FILENAME;
	}

	FilePos = (UINT)FS_Seek( FileHandle, (int)0, FS_FILE_CURRENT );
	*Position = FilePos;
	
	return FS_NO_ERROR;
}



// don't need, only ref
int FS_SetSeekHint(FS_HANDLE FileHandle, UINT HintNum, FS_FileLocationHint *Hint)
{
    return FS_NO_ERROR;
}

/*****************************************************************************
 * FUNCTION
 *  UCS2Strncpy
 * DESCRIPTION
 *  copies the one UCS2 encoded string to other
 *  
 *  In size pass no of characters not bytes
 * PARAMETERS
 *  strDestination      [OUT]       StrDest-> Destination array
 *  strSource           [IN]        
 *  size                [IN]        
 * RETURNS
 *  PS8 -> pointer to destination string or NULL
 *****************************************************************************/
S8 *UCS2Strncpy(S8 *strDestination, const S8 *strSource, U32 size)
{
#ifndef __RESOURCE_GEN_
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    /* On the Target */
    return (S8*)app_ucs2_strncpy(
                    (char*)strDestination,
                    (const char*)strSource,
                    (kal_uint32)size);

#else
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    U16 count = 1;
    U32 count1 = 0;
    S8 *temp = strDestination;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    size = size * 2;

    MMI_ASSERT(!(strDestination == NULL));

    while (!((*(strSource + count) == 0) && (*(strSource + count - 1) == 0)) && (count1 < size))
    {

        *(strDestination + count - 1) = *(strSource + count - 1);
        *(strDestination + count) = *(strSource + count);
        count += 2;
        count1 += 2;
    }

    *(strDestination + count - 1) = '\0';
    *(strDestination + count) = '\0';

    return temp;
#endif
}


unsigned short app_unicode_n_to_ansii(char *pOutBuffer, char *pInBuffer, unsigned long len)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/

    return app_ucs2_str_n_to_asc_str(pOutBuffer, pInBuffer, len);
}


// get time 
void  DTGetRTCTime(MYTIME *mTime)
{
	mTime->DayIndex =1;
	mTime->nDay =1;
	mTime->nMonth =1;
	mTime->nYear = 2111;
	mTime->nSec = 1;
	mTime->nMin = 1;
	mTime->nHour =1;
}

boolean  mmi_dt_is_valid(MYTIME *mTime)
{

	return TRUE;
}



//
//---------------------------------------------------------------------------------
void	drm_test( void )
{
    FS_HANDLE 	object;
    kal_char 	*buffer = NULL;
	WCHAR		wFpath[256] = { 0 };
	uint32 		size, length;


    buffer = (kal_char*)get_ctrl_buffer(256);
    ASSERT(buffer);

    memset( buffer, 0, sizeof(buffer) );

	STRCPY( (char*)buffer, (const char*)"fs:/shared/ftl/Received/LTtest.drm" );
	_AsciiStr2Unicode( (_LPBYTE)buffer, (_LPWORD)wFpath );


#if 1
    object = FS_Open( (const WCHAR*)wFpath, FS_READ_ONLY );
    if( object < FS_NO_ERROR )
    {
        free_ctrl_buffer(buffer);
        return ;
    }

	FS_Read( object, buffer, 18, (UINT*)&length );

	size = 0;
	size = FS_Seek( object, (int)0, FS_FILE_CURRENT );


	size = FS_Seek( object, (int)10, FS_FILE_CURRENT );

	size = 0;
	size = FS_Seek( object, (int)0, FS_FILE_CURRENT );

	FS_Close( object );

#else

    object = FS_Open( (const WCHAR*)wFpath, FS_READ_WRITE | FS_CREATE_ALWAYS);
    if( object < FS_NO_ERROR )
    {
        free_ctrl_buffer(buffer);
        return ;
    }

	size = STRLEN( (const char*)buffer );
	
	FS_Write(object, buffer, size, &length);

	if( object > 0 )
	{
		FS_GetFileSize( object, &size );
		FS_Close( object );
	}

	FS_Delete( (const WCHAR*)wFpath );

#endif

    free_ctrl_buffer(buffer);
}


//
//---------------------------------------------------------------------------------
void	drm_testDQ( void )
{
    drm_proc_enum returnValue;
    U8 			drm_serial = 0;
	WCHAR*		pwFilePath = NULL;
	WCHAR*		pwNewPath = NULL;
	kal_uint8	MimeStr[256] = { 0 };


	pwFilePath = (WCHAR*)MALLOC(256);
	if( !pwFilePath )
		return ;
	
	pwNewPath = (WCHAR*)MALLOC(256);
	if( !pwFilePath )
	{
		FREEIF(pwFilePath);
		return ;
	}
	
	STRCPY( (char*)MimeStr, (const char*)"fs:/sys/database/browser/inctestin.dm" );
	_AsciiStr2Unicode( (_LPBYTE)MimeStr, (_LPWORD)pwFilePath );

	STRCPY( (char*)MimeStr, (const char*)"fs:/sys/database/browser/nfdltmp.drm" );
	_AsciiStr2Unicode( (_LPBYTE)MimeStr, (_LPWORD)pwNewPath );

	STRCPY( (char*)MimeStr, (const char*)"application/vnd.oma.drm.message" );	
	returnValue = DRM_process_async_file( (kal_uint8 *) MimeStr,
											 (kal_wchar*) pwFilePath,
											 (kal_wchar*) pwNewPath,
											 ( (WSTRLEN(pwFilePath)+1+5) * 2 ),
											 (kal_uint8*) &drm_serial, 
											 MOD_MMI );


	FREEIF( pwFilePath );
	FREEIF( pwNewPath );
}


// 
// "fs:/sys/database/browser/nfPureData.drm"
// @pwPath: in
// @pName: out
//---------------------------------------------------------------------------------
boolean		DRM_GetFileName( kal_wchar *pwPath, kal_wchar *pName )
{
	int32	 	len = 0;
	WCHAR*	 	pMatch = NULL;
	WCHAR*   	pLast = NULL;


	if( !pwPath )
		return FALSE;

	// below as "http://wap.163.com/index.wml" etc, convert to "index"
	pMatch = wstrstr( pwPath, (_LPWORD)nf_str_line );		
	while( pMatch )
	{
		pLast = pMatch; // retain last laster p
		pMatch++ ;
		pMatch = wstrstr( pMatch, (_LPWORD)nf_str_line );
	}
	
	if( pLast )
	{
		pLast++ ;
		WSTRCPY( (AECHAR*)pName, (const AECHAR*)pLast );
	}
	else
	{
		WSTRCPY( (AECHAR*)pName, (const AECHAR*)nf_str_Noname );
	}

	return	TRUE;
}

